using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using DesktopApp.Models;
using DesktopApp.ViewModels;
using DesktopApp.Views; // Required for RuleEditorWindow, InputDialog, ConfirmationDialog
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;

namespace DesktopApp.ViewModels.Services
{
    public class RuleManagementService : IRuleManagementService
    {
        private readonly string _templatesFilePath;
        private readonly string _ruleSetsFilePath;
        private readonly IUIService _uiService;

        public RuleManagementService(IUIService uiService)
        {
            _uiService = uiService ?? throw new ArgumentNullException(nameof(uiService));

            // Define path for templates file
            var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            var appFolderPath = Path.Combine(appDataPath, "LogClearTool"); // App-specific folder
            Directory.CreateDirectory(appFolderPath); // Ensure directory exists
            _templatesFilePath = Path.Combine(appFolderPath, "templates.json");
            _ruleSetsFilePath = Path.Combine(appFolderPath, "rulesets.json");
            Debug.WriteLine($"RuleManagementService: Templates file path: {_templatesFilePath}");
            Debug.WriteLine($"RuleManagementService: Rule sets file path: {_ruleSetsFilePath}");
        }

        public Task<List<LogProcessingTemplate>> LoadTemplatesAsync()
        {
            List<LogProcessingTemplate> templates = new List<LogProcessingTemplate>();
            if (!File.Exists(_templatesFilePath))
            {
                Debug.WriteLine("RuleManagementService: Templates file not found. Loading samples.");
                templates.AddRange(LoadSampleTemplates());
                return Task.FromResult(templates);
            }

            try
            {
                Debug.WriteLine("RuleManagementService: Loading templates from file...");
                string json = File.ReadAllText(_templatesFilePath); // Sync read is ok for local file
                var loadedTemplates = JsonSerializer.Deserialize<List<LogProcessingTemplate>>(json);
                if (loadedTemplates != null && loadedTemplates.Any())
                {
                    templates.AddRange(loadedTemplates);
                    Debug.WriteLine($"RuleManagementService: Loaded {templates.Count} templates.");
                }
                else
                {
                     Debug.WriteLine("RuleManagementService: Templates file empty or invalid. Loading samples.");
                     templates.AddRange(LoadSampleTemplates());
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"RuleManagementService: Error loading templates file: {ex.Message}. Loading samples.");
                 templates.AddRange(LoadSampleTemplates()); // Load samples on error
            }
            return Task.FromResult(templates); // Return Task for interface compatibility
        }

        public Task SaveTemplatesAsync(IEnumerable<LogProcessingTemplate> templates)
        {
             try
            {
                Debug.WriteLine("RuleManagementService: Saving templates to file...");
                var options = new JsonSerializerOptions { WriteIndented = true };
                // Filter out the special "(所有规则)" item before saving
                var templatesToSave = templates.Where(t => t.Name != SpecialTemplateNames.AllRules).ToList();
                string json = JsonSerializer.Serialize(templatesToSave, options);
                File.WriteAllText(_templatesFilePath, json); // Sync write ok
                Debug.WriteLine("RuleManagementService: Templates saved successfully.");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"RuleManagementService: Error saving templates file: {ex.Message}");
                // TODO: Notify user of save failure?
            }
            return Task.CompletedTask; // Return Task for interface compatibility
        }

        public Task<List<RuleItemViewModel>> LoadRulesFromTemplateAsync(LogProcessingTemplate template)
        {
             if (template == null)
             {
                 return Task.FromResult(new List<RuleItemViewModel>()); // Return empty list
             }
             Debug.WriteLine($"RuleManagementService: Loading rules from template: {template.Name}");
             var rules = template.Rules.Select(def => def.ToViewModel()).ToList();
             return Task.FromResult(rules);
        }

        public async Task<LogProcessingTemplate?> SaveRulesAsTemplateAsync(IEnumerable<RuleItemViewModel> currentRules)
        {
            // Use UIService to show input dialog
            string? templateName = await _uiService.ShowInputDialogAsync("保存模板", "请输入模板名称:", $"我的模板");

            if (string.IsNullOrWhiteSpace(templateName))
            {
                Debug.WriteLine("RuleManagementService: Save template cancelled or name is empty via UI Service.");
                return null;
            }

            // Note: Duplicate name check might be better handled in the ViewModel before calling this service method.
            
            Debug.WriteLine($"RuleManagementService: Saving current rules as template: {templateName}");
            var newTemplate = new LogProcessingTemplate
            {
                Name = templateName,
                Rules = currentRules.Select(vm => new RuleDefinition(vm)).ToList()
            };

            // The service creates the template object, but the ViewModel will handle adding it
            // to its ObservableCollection and triggering the save of the whole list.
            return newTemplate; 
        }

        public async Task<bool> DeleteTemplateAsync(LogProcessingTemplate templateToDelete)
        {
             if (templateToDelete == null) return false;

             string templateName = templateToDelete.Name ?? "未命名模板";
             // Use UIService to show confirmation dialog
             bool confirmed = await _uiService.ShowConfirmationDialogAsync("确认删除模板", $"确定要删除模板 \"{templateName}\" 吗？模板中的规则也将被删除。");
             
             if (confirmed) 
             {
                 Debug.WriteLine($"RuleManagementService: Deletion confirmed for template: {templateToDelete.Name}");
             } 
             else 
             {
                 Debug.WriteLine("RuleManagementService: Delete template cancelled.");
             }
             return confirmed; // Return confirmation status. VM handles removal & saving.
        }

        public async Task<RuleItemViewModel?> AddRuleAsync()
        {
            Debug.WriteLine("RuleManagementService: AddRuleAsync called");
            var editorVm = new RuleEditorViewModel(); // Create ViewModel for new rule

            // Use UIService to show the editor dialog
            var resultRule = await _uiService.ShowRuleEditorDialogAsync(editorVm);

            if (resultRule != null)
            {
                Debug.WriteLine($"RuleManagementService: New rule created: {resultRule.Name}");
            }
            else
            {
                Debug.WriteLine("RuleManagementService: Rule addition cancelled.");
            }
            return resultRule; // Return the created rule (or null)
        }

         public async Task<RuleItemViewModel?> EditRuleAsync(RuleItemViewModel ruleToEdit)
         {
            if (ruleToEdit == null) return null;

            Debug.WriteLine($"RuleManagementService: EditRuleAsync called for: {ruleToEdit.Name}");
            var editorVm = new RuleEditorViewModel(ruleToEdit);

            // Use UIService to show the editor dialog
            var resultRuleData = await _uiService.ShowRuleEditorDialogAsync(editorVm);

            if (resultRuleData != null)
            {
                 Debug.WriteLine($"RuleManagementService: Rule edit confirmed for: {ruleToEdit.Name}. Returning updated data.");
                 // Return the data for the updated rule. The ViewModel will apply these changes.
                 return resultRuleData; 
            }
            else
            {
                Debug.WriteLine("RuleManagementService: Rule edit cancelled.");
                return null;
            }
         }

        public async Task<bool> ConfirmDeleteRuleAsync(RuleItemViewModel ruleToDelete)
        {
             if (ruleToDelete == null) return false;

            string ruleName = ruleToDelete.Name ?? "未命名规则";
            // Use UIService to show confirmation dialog
            bool confirmed = await _uiService.ShowConfirmationDialogAsync("确认删除规则", $"确定要删除规则 \"{ruleName}\" 吗？此操作无法撤销。");

            if (confirmed)
            {
                 Debug.WriteLine($"RuleManagementService: Deletion confirmed for rule: {ruleToDelete.Name}");
            }
            else
            {
                 Debug.WriteLine("RuleManagementService: Delete rule cancelled.");
            }
             return confirmed; // Return confirmation status. VM handles removal.
        }

        // --- Rule Set Method Implementations ---
        public Task<List<RuleSet>> LoadRuleSetsAsync()
        {
            List<RuleSet> ruleSets = new List<RuleSet>();
            if (!File.Exists(_ruleSetsFilePath))
            {
                Debug.WriteLine("RuleManagementService: Rule sets file not found. Returning empty list.");
                // Optionally load sample rule sets here if desired
                return Task.FromResult(ruleSets);
            }

            try
            {
                Debug.WriteLine("RuleManagementService: Loading rule sets from file...");
                string json = File.ReadAllText(_ruleSetsFilePath);
                var loadedRuleSets = JsonSerializer.Deserialize<List<RuleSet>>(json);
                if (loadedRuleSets != null)
                {
                    ruleSets.AddRange(loadedRuleSets);
                    Debug.WriteLine($"RuleManagementService: Loaded {ruleSets.Count} rule sets.");
                }
                else
                {
                     Debug.WriteLine("RuleManagementService: Rule sets file empty or invalid. Returning empty list.");
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"RuleManagementService: Error loading rule sets file: {ex.Message}. Returning empty list.");
                // Consider notifying the user via _uiService?
            }
            return Task.FromResult(ruleSets);
        }

        public Task SaveRuleSetsAsync(IEnumerable<RuleSet> ruleSets)
        {
             try
            {
                Debug.WriteLine("RuleManagementService: Saving rule sets to file...");
                var options = new JsonSerializerOptions { WriteIndented = true };
                // Ensure we are saving a List<RuleSet>
                string json = JsonSerializer.Serialize(ruleSets.ToList(), options);
                File.WriteAllText(_ruleSetsFilePath, json);
                Debug.WriteLine("RuleManagementService: Rule sets saved successfully.");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"RuleManagementService: Error saving rule sets file: {ex.Message}");
                // Consider notifying the user via _uiService?
            }
            return Task.CompletedTask;
        }

        // --- Helper Methods ---

        private List<LogProcessingTemplate> LoadSampleTemplates()
        {
            // Copied from MainWindowViewModel
             return new List<LogProcessingTemplate>
             {
                 new LogProcessingTemplate
                 {
                    Name = "仅清理时间戳",
                    Rules = new List<RuleDefinition> { new RuleDefinition { Name="清理时间戳", Type=RuleType.RemoveTimestamps, IsEnabled=true } }
                 },
                 new LogProcessingTemplate
                 {
                    Name = "清理时间和路径",
                    Rules = new List<RuleDefinition>
                    {
                        new RuleDefinition { Name="清理时间戳", Type=RuleType.RemoveTimestamps, IsEnabled=true },
                        new RuleDefinition { Name="清理文件路径", Type=RuleType.RemoveFilePaths, IsEnabled=true }
                    }
                 }
             };
        }

         // Example of how to get the main window, similar to LogFileService
         // Could be passed in or obtained differently depending on DI setup.
         // Replaced by Func<Window?> injection
         /*
         private static Window? GetMainWindow()
         {
            if (Avalonia.Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
            {
                return desktop.MainWindow;
            }
            return null;
         }
         */
    }
} 